package com.teach3;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Iterator;
import java.util.UUID;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;

/**
 * <pre>
 * - 屏幕广播 
 * Author : J.L.Zhou
 * E-Mail : 2233875735@qq.com
 * Tel : 151 1104 7708
 * Date : 2021-4-29 15:13:56
 * Version : 1.0
 * Copyright 2021 jlzhou.top Inc. All rights reserved.
 * Warning: this content is only for internal circulation of the company.
 *          It is forbidden to divulge it or use it for other commercial purposes.
 * </pre>
 */
public class ScreenServer {

	private static Robot robot;
	private static Rectangle rectangle;
	private static Jpeg jpeg;

	public static void main(String[] args) throws Exception {
		
		try {
			jpeg = new Jpeg(0.1f);//创建jpeg压缩质量为0.1的JPEG图片输出对象
			robot = new Robot();//机器人
			Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
			rectangle = new Rectangle(0, 0, (int) dimension.getWidth(), (int) dimension.getHeight());
			Thread.sleep(2000);
			

			// 1.创建对象
			// 构造数据报套接字并将其绑定到本地主机上任何可用的端口。
			DatagramSocket socket = new DatagramSocket();

			// 3.发送
			Thread t1 = new Thread(() -> {
				while (true) {
					try {
						Thread.sleep(50);
						ByteArrayOutputStream out = new ByteArrayOutputStream();
						getScreen(out);//使用低质量<64k发送
						byte[] arr = out.toByteArray();
						DatagramPacket packet = new DatagramPacket(arr, arr.length,
								InetAddress.getByName("192.168.31.112"),5000);
						socket.send(packet);
						//System.out.println("发送中");
					} catch (Exception e) {
						break;
					}
				}
			});
//			getScreen(new FileOutputStream(new File("d:/upload/"+UUID.randomUUID().toString()+".jpg")));
			t1.start();
			t1.join();
			// 4.关闭资源
			socket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	
	}

	public static void getScreen(OutputStream out) throws Exception {
		BufferedImage bi = robot.createScreenCapture(rectangle);
		jpeg.jpeg(bi, out);
	}

	
	
	
	//下面是设想，高质量，拆分打包发送，未完成
	/**
	 * [图片序号] [块编号] [总块数] [65536-3]
	 * 
	 * @param out
	 */
	private final static int MAX = 65533;
	private static byte imageNum = Byte.MIN_VALUE;

	public static synchronized byte[][] split64k(ByteArrayOutputStream out) {
		if (imageNum == Byte.MAX_VALUE) {
			imageNum = Byte.MIN_VALUE;
		} else {
			imageNum++;
		}
		byte[] all = out.toByteArray();
		byte row = (byte) ((all.length - 1) / MAX + 1);

		byte[][] ret = new byte[row][];

		for (int i = 0; i < row; i++) {
			ret[i] = new byte[MAX + 3];
			ret[i][0] = imageNum;
			ret[i][1] = (byte) i;
			ret[i][2] = row;
			System.arraycopy(all, i * MAX, ret[i], 3, MAX);//有问题

		}

		return ret;

	}
	
	private static class Jpeg {
		
		private ImageWriter writer;
		private IIOImage iIamge;
		private ImageWriteParam iwp;

		public Jpeg(float quality) {
			Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");// 得到迭代器
			writer = (ImageWriter) iter.next(); // 得到writer

			// 得到指定writer的输出参数设置(ImageWriteParam )
			iwp = writer.getDefaultWriteParam();
			iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
			iwp.setCompressionQuality(quality); // 设置压缩质量参数

			iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);

			ColorModel colorModel = ColorModel.getRGBdefault();
			// 指定压缩时使用的色彩模式
			iwp.setDestinationType(
					new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
		}

		public void jpeg(BufferedImage image, OutputStream out) {
			// 如果图片空，返回空
			if (image == null) {
				return;
			}

			iIamge = new IIOImage(image, null, null);
			try {
				// 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
				// 通过ImageIo中的静态方法，得到byteArrayOutputStream的ImageOutput
				writer.setOutput(ImageIO.createImageOutputStream(out));
				writer.write(null, iIamge, iwp);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}
